package com.google.code.solrdimension.querymodifiers;

import java.util.Arrays;
import java.util.List;

import org.apache.solr.client.solrj.SolrQuery;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.code.solrdimension.config.QueryParamConstants;
import com.google.code.solrdimension.config.DimensionConfigWrapper;
import com.google.code.solrdimension.config.StaticConfiguration;
import com.google.code.solrdimension.config.dimension.DimensionConfig;
import com.google.code.solrdimension.config.dimensionvalue.ExactDimensionValueConfig;
import com.google.code.solrdimension.parsers.exception.SolrDimensionException;
import com.google.code.solrdimension.solrqueryutil.QueryUtil;

public class QueryModifierImpl implements QueryModifier {

    private static Logger logger = LoggerFactory.getLogger(QueryModifierImpl.class);
    

    public SolrQuery prepareQuery(SolrQuery query, DimensionConfigWrapper solrDimensionConfig) throws SolrDimensionException{
        
        if (query == null || solrDimensionConfig == null){
            throw new SolrDimensionException("Expecting SolrQuery and SolrDimensionConfig, but get null");
        } else {
            query.setFacet(true);
            
            List<String> filters = null;
            
            if (query.getFilterQueries() != null){
                filters = Arrays.asList(query.getFilterQueries());
            }
            
            
            for (DimensionConfig dimensionConfig :  solrDimensionConfig.getDimensionConfigs()){

                //first check if the DimesnionConfig should appear (i.e. The dependOn attribute in the XML file
                //is fulfilled
                if (dimensionConfig.getDependOn() == null || QueryUtil.isDimensionIdInFilter(dimensionConfig.getDependOn(), filters)){
                   
                    
                    
                    if (logger.isDebugEnabled()){
                        if (dimensionConfig.getDependOn() != null &&  QueryUtil.isDimensionIdInFilter(dimensionConfig.getDependOn(), filters)){
                            logger.debug("The DimensionConfig: " + dimensionConfig.getDisplayName() + " is depend on dimensionConfig with ID: " + dimensionConfig.getDependOn());
                        }
                    }
                    
                    String facetFieldName = null;
                    
                    if (dimensionConfig.getType().equals(DimensionConfig.TYPE_DEFAULT)){
                        facetFieldName = dimensionConfig.getSolrFieldName();
                    } else {
                        
                        if (dimensionConfig.getDimensionValueConfigs().get(0) instanceof ExactDimensionValueConfig){
                            facetFieldName = StaticConfiguration.FIELD_PREFIX + dimensionConfig.getId();
                        } else {
                            facetFieldName = StaticConfiguration.MULTI_VALUED_FIELD_PREFIX + dimensionConfig.getId();
                        }
                        
                    }
                    
                    query.addFacetField(facetFieldName);
                    
                    if (dimensionConfig.getValueOrder() != null){
                        
                        String paramName = QueryParamConstants.FACET_SORT_QUERY.replaceAll(QueryParamConstants.FACET_SORT_QUERY_REPLACE, facetFieldName);
                        
                        if (dimensionConfig.getValueOrder().equals(DimensionConfig.INDEX_VALUE_ORDER)){
                            
                            query.add(paramName, QueryParamConstants.FACET_SORT_INDEX_VAL);
                        } else if (dimensionConfig.getValueOrder().equals(DimensionConfig.FREQUENCY_VALUE_ORDER)){
                            query.add(paramName, QueryParamConstants.FACET_SORT_COUNT_VAL);
                        }
                    }
                    
                } else {
                    if (logger.isDebugEnabled()){
                        if (dimensionConfig.getDependOn() != null){
                            logger.debug("DimensionConfig: " + dimensionConfig.getDisplayName() + " is depend on " + dimensionConfig.getDependOn() + ", which is not in the filter: " + (filters==null?"":filters) );
                            
                            
                        }
                    }
                    
                }
                
            }
        }
        
        
        return query;
        
    }
    

    
}
